Datenbank-Container
Rainer Becker
Die wesentliche Erweiterung von Visual FoxPro im Datenbankbereich sind die neuen Datenbank-Container. Ein DBC fast bestehende Tabellen zu einer Gesamt-Datenbank zusammen
und ist selbst auch wieder nur eine Tabelle. Die Gesamtheit von Datenbank-Container mit allen in ihm definierten Tabellen ergibt dann die eigentliche Datenbank.
Diese ist physisch zwar über verschiedene Plätze verstreut, logisch aber eine Einheit. Den DBC sollte man jedoch keinesfalls mit einem Data-Dictionary verwechseln, denn die
Tabellenstrukturen befinden nach wie vor im Header der DBF-Datei und die Indexstrukturen sind nach wie vor im Header der CDX-Datei. Der Datenbank-Container ist also nur
zusätzlich/ergänzend zu vorhandenen Tabellen. Ein Neuerzeugen von Tabellen oder Indizes ist aus den Informationen im Datenbank-Container nicht möglich.
Grundbefehle
Für das Arbeiten mit dem Datenbankcontainer gibt es ein halbes Dutzend neuer Grundbefehle. Erstmal legt man sich einen leeren DBC mit CREATE DATABASE an. Öffnen und
Schließen kann man ihn mit OPEN bzw. CLOSE DATABASE. Visuell ändern kann man einen Container dann mit MODIFY DATABASE. Und da man jede Menge Container offen haben
kann, muß man zwischen ihnen ja auch wechseln können. Dafür ist SET DATABASE TO zuständig. Falls man einen DBC wieder loswerden will darf man ihn nur mit dem Befehl DELETE
DATABASE löschen, da sonst die Referenzen in den verbundenen Tabellen nicht entfernt werden und man diese nicht mehr ohne weiteres öffnen kann. Wahlweise kann man mit der
zusätzlichen Befehlsklausel DELETETABLES die Tabellen auch gleich mitlöschen. Wenn einem das versehentlich passiert, hat man einen schnellen Super-ZAP, zu der langsamen
Variante kommen wir später.
Inhaltsanzeige
Für die Anzeige des Inhalts eines Datenbankcontainers gibt es eine Reihe neuer Klauseln für entsprechende LIST bzw. DISPLAY-Befehle. Interaktiv Anzeigen lassen kann man sich den
Gesamtinhalt (LIST / DISPLAY DATABASE), die enthaltenen Tabellen (LIST / DISPLAY TABLES), die enthaltenen Views (LIST / DISPLAY VIEWS), die definierten
ODBC-Verbindungen (LIST / DISPLAY CONNECTIONS) sowie die gespeicherten Prozeduren/Funktionen (LIST / DISPLAY PROCEDURES). Per Umleitung der Ausgabe in eine Textdatei
kann man so auch schnell Vorlagen für eine Dokumentation erstellen.
Sonstige Befehle
Zwar sind Datenbankcontainer eigentlich auch nur Tabellen, aber die Funktionen DBF() und USED() kann man auf diese leider nicht anwenden. Stattdessen gibt es DBC() und DBUSED().
Zur schnellen Information über Datenbankcontainer gibt es die Funktion ADATABASES(), die ein Array aller offenen Datenbankcontainer zurückliefert, sowie ADBOBJECTS() mit einem
Array aller Einträge im aktuellen Datenbankcontainer.
Um Details über die Eigenschaften eines DBCs zu ermitteln oder zu setzen, gibt es das neue Funktionspaar DBGETPROP() und DBSETPROP(). Get- und Set-Funktionen für Properties
begegnen einem in Visual FoxPro übrigens häufiger und sie sind alle sehr ähnlich. Bei häufigen Änderungen der im DBC enthaltenen Einträge sowie nach dem Entfernen von Tabellen
kann man den DBC mit PACK DATABASE wie eine normale Tabelle komprimieren. Zusätzlich gibt es noch eine Verifizier-Funktion zwecks Abgleich der im Container gespeicherten
Strukturen mit den real vorhandenen Tabellen. VALIDATE DATABASE liefert derzeit leider nur eine interaktive Fehlermeldung zurück und keine Fehlernummer.
Tabellen und Container
Nicht nur mit dem kleinen DBC-Toolbar kann man bestehende Tabellen in einen DBC einfügen, sondern auch programmatisch ist dies mit ADD TABLE möglich. Ob eine Tabelle in einen
Container eingefügt wurde, kann man mit der Funktion INDBC() abfragen. Mit REMOVE TABLE kann man aus dem aktiven Datenbankcontainer eine Tabelle entfernen. Der Rückverweis
in der Tabelle wird gleichzeitig mit entfernt. Mit der zusätzlichen Befehlsklausel DELETE kann man auch gleich die Tabelle selbst löschen lassen Alternativ gibt es noch den Befehl FREE
TABLE, welcher nur die Rückreferenz in der Tabelle auf den Container entfernt.
Felder in Tabellen
Jetzt haben wir die Tabellen im Container, der nächste Schritt ist jetzt die Feindefinition der Felder innerhalb der Tabellen. Und da ergeben sich mit dem DBC doch sehr praktikable neue
Fähigkeiten. Außer das Tabellennamen und Feldbezeichnungen im Container bis zu 128 Zeichen lang sein können, gibt es je Feld auch noch ein halbes Dutzend neuer Eigenschaften.
Die erste Feldeigenschaft stellt sich als weitere Spalte im MODI-STRU-Dialog dar und hat die Überschrift NULL. Damit kann man bei SET NULL ON festlegen, daß ein Feld auch den Wert
.NULL. enthalten darf. Bitte nur verwenden, wenn einem wirklich klar ist, worauf man sich da eigentlich einläßt. Unter DEFAULT kann man endlich Default-/Vorgabe-Wert für neue Sätze
festlegen. Bei APPEND BLANK oder INSERT stehen die Vorgaben automatisch in den ansonsten leeren Feldern. Dabei muß es sich übrigens nicht um Konstanten handeln, sondern
auch Funktionsaufrufe sind zulässig. Letzteres sei insbesondere bei Feldern die zu einem CANDIDATE- oder PRIMARY-Schlüssel gehören sehr empfohlen, weil man sonst sofort eine
Fehlermeldung bekommt.
Mit dem Zusatzfeld CAPTION kann man endlich Überschriften eingeben und muß sich Kopfzeilen für BROWSE-Fenster nicht mehr mühsam selbst zusammenstellen. Außerdem
verwendet der Masken-Assistent die CAPTION für den Feldtitel in neu erstellten Masken. Für Grids wird die Caption zwar nicht automatisch mit eingebaut, aber man kann sich diese ja
zur Laufzeit mit DBGETPROP() aus dem Datenbankcontainer laden.
Richtig spannend wird es bei der Eigenschaft VALIDATION RULE. Hier benennt man eine Valid-Klausel auf Feldebene, die man sinnvoller Weise gleich im DBC direkt abspeichert (siehe
unten). Je nach Einstellung beim Buffering wird diese beim Verlassen vom Datenfeld oder erst beim eigentlichen Abspeichern ausgewertet. Die entsprechende Textmeldung im Fehlerfall
kann man gleich in VALIDATION TEXT ablegen. Eine VALIDATION RULE und einen VALIDATION TEXT kann man übrigens in einer Zusatzmaske nicht nur zu einem Datenfeld
sondern auch gleich zum ganzen Datensatz abspeichern.
An die Dokumentation wurde ansonsten auch etwas mehr gedacht als früher und man kann in COMMENT einen Kommentar oder eine Notiz zum Feld eingeben.
Primärschlüssel
Auch im Bereich der Indizes gibt es noch eine weitere Neuerung. Diese ist aber eher kosmetischer Natur. Bisher kannten wir ja schon die Indexarten REGULAR und UNIQUE. Neu ist die
Indexart CANDIDATE, die wirklich eindeutig ist und bei Einfügeversuchen von Duplikaten mit einer Fehlermeldung reagiert. Im Datenbank-Container kann man nunmehr einen beliebigen
CANDIDATE-Index (es könnte evtl. ja mehrere geben und alle sind "Kandidaten" oder deutsch "Alternativschlüssel") zum Primärschlüssel, kurz PRIMARY, erklären. Welcher Index der
Primärschlüssel ist, kann mit der Funktion PRIMARY() abgefragt werden. Soviel dazu. Was es leider nicht gibt, ist ein Zählerfeld bzw. ein inkrementeller Index (soetwas wie eine wirklich
eindeutige Satznummer, die auch ein PACK überlebt). Aber dies kann man sich relativ einfach selbst bauen.
Gespeicherte Prozeduren
Gespeicherte Prozeduren, besser bekannt unter der englischen Bezeichnung "Stored Procedures", werden ebenfalls im Datenbankcontainer verwaltet. Die Implementation entspricht
vielleicht nicht ganz der einschlägigen Fachliteratur, ist aber sehr sehr gut gelungen. Im Prinzip kann man beliebige Funktionen und Prozeduren direkt im Datenbankcontainer speichern
und in der Praxis wirkt sich das wie eine Datenbank-spezifische Prozedur-Datei a la SET PROCEDURE TO aus. Mit LIST PROCEDURE kann man sich eine Übersicht über die
Funktionsnamen geben und mit MODIFY PROCEDURE kann man ein Bearbeitungsfenster dafür öffnen. Der Befehl COPY PROCEDURES dient zum Exportieren der Prozeduren eines
Containers in eine Textdatei. Und mit APPEND PROCEDURES kann man Prozeduren aus einer Datei anhängen oder optional mit der Klausel OVERWRITE die bestehenden Funktionen
überschreiben. Die beiden letztgenannten Befehle waren zumindest in der Beta-Phase sehr wichtig, da sich die DBC-Strukturen öfters änderten und man so wenigstens seine Programme
retten konnte. Und was für Funktionen speichert man nun an dieser Stelle statt irgendwo im Programm? Alle Funktionen die von Feldern oder Tabellen im Container beim Speichern von
Datensätzen aufgerufen werden könnten! Dadurch bilden Daten und zugehörige Funktionen eine Einheit und diese sollte man soweit wie möglich kapseln - damit auch der zukünftige
ODBC-Treiber diese verwenden kann und auch "Kurpfuscher" mit Excel einem keinen Schrott mehr in die Tabellen hauen können!
Zusammenfassung
Die wesentliche Eigenschaften des Datenbankcontainers in Bezug auf Tabellen haben wir nun behandelt. Wichtig und interessant sind aber auch die neuen Möglichkeiten zur Definition
von Relationen sowie die darauf beruhenden Trigger zur Einhaltung der referentiellen Integrität. Und sehr praktisch sind die neuen lokalen und remote SQL-Views - dazu in einem anderen
Artikel mehr.
Rainer Becker, seit 1985 in der Programmierung tätig, ist Geschäftsführer der ISYS GmbH sowie der W&B GmbH und leitet die deutschsprachige FoxPro User Group. Tätigkeitsschwerpunkte sind Beratung/Coaching für FoxPro-Projekte
sowie die Entwicklung von Lösungen im Verlags- und Schulbereich. Sie erreichen Ihn unter redaktion@dfpug.de oder per Telefax unter 06173-950904.
CopyRight © 1996 by dFPUG c/o ISYS GmbH bzw. beim entsprechenden Verfasser
|